import { V2Util, IPos, ISize, IAng } from "../util/V2Util"

const v2 = V2Util

/** 构造参数接口 */
export interface IBase {
    x?: number,
    y?: number,
    /** 宽 */
    w?: number,
    /** 高 */
    h?: number,
    /** 角度 */
    ang?: number
}

/** 物体基类 */
export default abstract class Base implements IPos, ISize, IAng {

    x: number
    y: number
    /** 宽 */
    w: number
    /** 高 */
    h: number
    /** 角度 */
    ang: number
    /** 弧度 */
    get rad() { return v2.ang2rad(this.ang) }

    constructor(obj: IBase = {}) {
        let { x = 0, y = 0, w = 0, h = 0, ang = 90 } = obj
        this.x = x
        this.y = y
        this.w = w
        this.h = h
        this.ang = ang
    }

    /** 设置参数 */
    set(obj: IBase = {}) {
        let { x = 0, y = 0, w = 0, h = 0, ang = 90 } = obj
        this.x = x
        this.y = y
        this.w = w
        this.h = h
        this.ang = ang
        return this
    }

    /** 设置坐标点 */
    pos(pos: IPos) {
        this.x = pos.x
        this.y = pos.y
        return this
    }

    /** 偏移坐标点 */
    offsetPos(pos: IPos) {
        this.x += pos.x
        this.y += pos.y
        return this
    }

    /** 设置宽度 */
    setW(w: number) {
        this.w = w
        return this
    }

    /** 偏移宽度 */
    offsetW(w: number) {
        this.w += w
        return this
    }

    /** 设置角度 */
    setAng(ang: number) {
        this.ang = ang
        return this
    }

    /** 偏移角度 */
    offsetAng(ang: number) {
        this.ang += ang
        return this
    }

    /** 获取朝向目标的角度 */
    angTo(pos: IPos) {
        return v2.rad2ang(v2.radTo(this, pos))
    }

    /** 朝弧度方向移动 */
    move(rad: number, dis: number) {
        let { x, y } = v2.move(this, rad, dis)
        this.x = x;
        this.y = y;
        return this;
    }

    /** 朝相对于目标弧度方向移动 */
    moveTo(obj: Base, dis: number) {
        return this.move(v2.radTo(this, obj), dis)
    }

    /** 朝当前弧度方向移动 */
    moveForward(dis: number) {
        return this.move(this.rad, dis)
    }

    /** 获取与目标的距离 */
    dis(pos: IPos) {
        return v2.dis(this, pos)
    }

    /** 复制 */
    abstract cp(): Base
    /** 判断是否与目标碰撞 */
    abstract collide(obj: Base): boolean
    /** 判断是否被目标包含 */
    abstract in(obj: Base): boolean
}